﻿namespace CryptoQrUtilities
{
    using System.Drawing;
    using ZXing;
    using ZXing.Common;
    using ZXing.QrCode;

    /// <summary>
    /// Urilities for handling simple tasks of QR encoding and decoding via bitmap media.
    /// Not thread-safe.
    /// </summary>
    public class QrUtilitiesWrapper
    {
        private const int c_defaultQrHeight = 300;
        private const int c_defaultQrWidth = 300;

        /// <summary>
        /// A specialized QR decoder.
        /// </summary>
        private static QRCodeReader s_qrReader = new QRCodeReader();

        /// <summary>
        /// Tries to read a given bitmap as QR encoding.
        /// </summary>
        /// <returns>The result of the QR reading. 'null': If no QR was identified.</returns>
        /// <param name="qrImage">The QR image to decode.</param>
        public Result GetQrDecoding(Bitmap qrImage)
        {
            Result qrDecode = null;
            var qrBinary = new BinaryBitmap(new HybridBinarizer(new BitmapLuminanceSource(qrImage)));

            qrDecode = s_qrReader.decode(qrBinary);

            if (qrDecode == null || qrDecode.RawBytes == null)
            {
                return null;
            }

            return qrDecode;
        }

        /// <summary>
        /// Encodes a given text string into a bitmap image.
        /// </summary>
        /// <returns>The QR encoded bitmap.</returns>
        /// <param name="text">The text to encode.</param>
        /// <param name="imageWidth">A required width for the returned image.</param>
        /// <param name="imageHeight">A required height for the returned image.</param>
        public Bitmap GetQrEncoding(string text, int imageWidth = c_defaultQrWidth, int imageHeight = c_defaultQrHeight)
        {
            var barcodeWriter = new BarcodeWriter
            {
                Format = BarcodeFormat.QR_CODE,
                Options = new EncodingOptions
                {
                    Height = imageHeight,
                    Width = imageWidth
                }
            };

            return barcodeWriter.Write(text);
        }
    }
}

